﻿using System;
using System.Collections.Generic;
using System.Text;
using NUnit.Framework;
using System.IO;
using System.Reflection;
using Langexplr.Abc;
using Microsoft.FSharp.Core;


namespace AbcLibrary.Tests
{
    

    [TestFixture]
    public class BodyIdentificationTests : BaseClassTestFixture
    {
     

        [Test]
        public void TestBasicBodyIdentification()
        {
            using (BinaryReader reader = new BinaryReader(Assembly.GetExecutingAssembly().GetManifestResourceStream("AbcLibrary.Tests.files.optionalparameters.as3.abc")))
            {

                List<AvmClass> classes = LoadClass(reader);

                Assert.IsTrue(classes[0].Methods.Head.Name.ToString().EndsWith("foo"));

                AvmMethod m = classes[0].Methods.Head.Method;

                Assert.IsTrue(Option<AvmMethodBody>.get_IsSome(
                    m.Body));

                AvmMethodBody body = m.Body.Value;

                
                var instructions = body.Instructions;

                Assert.AreEqual(6, instructions.Length);
                Assert.AreEqual("getlocal_0", instructions[0].Name);
                Assert.AreEqual("pushscope", instructions[1].Name);
                Assert.AreEqual("getlocal_1", instructions[2].Name);
                Assert.AreEqual("getlocal_1", instructions[3].Name);
                Assert.AreEqual("multiply", instructions[4].Name);
                Assert.AreEqual("returnvalue", instructions[5].Name);

              //  System.Diagnostics.Debugger.Break();
                var x = AbcFileInstruction.AsType(21);
                Console.WriteLine(x.Name);


            }

        }

        [Test]
        public void TestHelloBodyIdentification()
        {
            using (BinaryReader reader = new BinaryReader(Assembly.GetExecutingAssembly().GetManifestResourceStream("AbcLibrary.Tests.files.hello.abc")))
            {

                AbcFile file = AbcFile.ReadFrom(reader);
                Assert.AreEqual(1, file.Scripts.Length);
                AvmScript script = AvmScript.Create(file.Scripts[0], file.Methods, file.MethodBodies,file.Instances, file.ConstantPool,new QualifiedName[]{});

                var instructions = script.InitMethod.Body.Value.Instructions;

                Assert.AreEqual(10, instructions.Length);
                Assert.AreEqual("getlocal_0", instructions[0].Name);
                Assert.AreEqual("pushscope", instructions[1].Name);
                Assert.AreEqual("findpropertystrict", instructions[2].Name);Assert.AreEqual("findpropertystrict", instructions[2].Name);

                QualifiedName name =
                    ((AbcFileInstruction._FindPropertyStrict)instructions[2])._FindPropertyStrict1;
                //QualifiedName name = file.ConstantPool.SolveMultiName(propMultinameIndex);
                
                Assert.IsTrue(QualifiedName.tag_MQualifiedName == name.Tag );
                QualifiedName._MQualifiedName qName =
                    (QualifiedName._MQualifiedName)name;
                Assert.AreEqual("print",qName._MQualifiedName2);
                Assert.AreEqual(2, qName._MQualifiedName1.Length);
                Assert.AreEqual("", qName._MQualifiedName1[0]._Ns1);
                Assert.AreEqual("hello.as$1", qName._MQualifiedName1[1]._Ns1);
                
                Assert.AreEqual("pushstring", instructions[3].Name);
                Assert.AreEqual("callprop", instructions[4].Name);
                Assert.AreEqual("coerce_a", instructions[5].Name);
                Assert.AreEqual("setlocal_1", instructions[6].Name);                
                Assert.AreEqual("getlocal_1", instructions[7].Name);
                Assert.AreEqual("returnvalue", instructions[8].Name);
                Assert.AreEqual("kill", instructions[9].Name);

                //  System.Diagnostics.Debugger.Break();
                var x = AbcFileInstruction.AsType(21);
                Console.WriteLine(x.Name);


            }

        }
    }
}

